package cn.lblbc.webbrowser.utils

import android.app.DownloadManager
import android.content.Context
import android.net.Uri
import android.os.Environment
import android.webkit.CookieManager
import android.webkit.URLUtil
import android.widget.Toast
import cn.lblbc.webbrowser.R
import java.io.File

class DownloadUtils(private val context: Context) {
    private val downloadManager: DownloadManager by lazy {
        context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
    }

    fun downloadFile(url: String, userAgent: String, contentDisposition: String, mimeType: String) {
        try {
            // 记录详细的下载请求信息
            println("【下载调试】开始处理下载请求")
            println("【下载调试】URL: $url")
            println("【下载调试】User-Agent: $userAgent")
            println("【下载调试】Content-Disposition: $contentDisposition")
            println("【下载调试】MIME类型: $mimeType")
            println("【下载调试】Android版本: ${android.os.Build.VERSION.SDK_INT}")
            println("【下载调试】设备型号: ${android.os.Build.MODEL}")
            
            // 首先检查是否是百度APK下载链接
            if (isBaiduApkDownloadUrl(url)) {
                println("【下载调试】检测到百度APK下载链接")
                // 如果是百度APK下载链接，直接使用APK扩展名
                val timestamp = System.currentTimeMillis()
                val fileName = "baidu_app_$timestamp.apk"
                downloadWithFileName(url, userAgent, fileName, mimeType)
                return
            }
            
            // 获取文件名
            var fileName = URLUtil.guessFileName(url, contentDisposition, mimeType)
            
            // 如果文件名为空，使用时间戳作为文件名
            if (fileName.isNullOrEmpty()) {
                fileName = "download_${System.currentTimeMillis()}"
                
                // 尝试从URL中提取文件扩展名
                val urlExtension = extractExtensionFromUrl(url)
                if (urlExtension.isNotEmpty()) {
                    fileName += ".$urlExtension"
                }
                // 如果URL中没有扩展名，则根据MIME类型添加适当的扩展名
                else if (!mimeType.isNullOrEmpty()) {
                    when {
                        mimeType.contains("image/") -> fileName += ".jpg"
                        mimeType.contains("video/") -> fileName += ".mp4"
                        mimeType.contains("audio/") -> fileName += ".mp3"
                        mimeType.contains("application/pdf") -> fileName += ".pdf"
                        mimeType.contains("application/zip") -> fileName += ".zip"
                        mimeType.contains("application/vnd.android.package-archive") -> fileName += ".apk"
                        mimeType.contains("text/") -> fileName += ".txt"
                        else -> fileName += ".bin"
                    }
                } else {
                    fileName += ".bin"
                }
            } else if (!fileName.contains(".")) {
                // 文件名不包含扩展名
                if (isBaiduApkDownloadUrl(url)) {
                    fileName += ".apk"
                } else {
                    // 尝试从URL中提取文件扩展名
                    val urlExtension = extractExtensionFromUrl(url)
                    if (urlExtension.isNotEmpty()) {
                        fileName += ".$urlExtension"
                    } else if (!mimeType.isNullOrEmpty() && mimeType.contains("application/vnd.android.package-archive")) {
                        fileName += ".apk"
                    }
                }
            } else if (fileName.endsWith(".bin") && isBaiduApkDownloadUrl(url)) {
                // 如果文件名以.bin结尾，但URL是百度APK下载链接，则替换扩展名为.apk
                fileName = fileName.substring(0, fileName.length - 4) + ".apk"
            }
            
            downloadWithFileName(url, userAgent, fileName, mimeType)
        } catch (e: Exception) {
            try {
                Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show()
            } catch (e: Exception) {
                // 忽略Toast显示错误
                e.printStackTrace()
            }
            e.printStackTrace()
        }
    }
    
    /**
     * 使用指定的文件名下载文件
     */
    private fun downloadWithFileName(url: String, userAgent: String, fileName: String, mimeType: String = "application/octet-stream") {
        try {
            println("【下载调试】准备下载文件")
            println("【下载调试】URL: $url")
            println("【下载调试】文件名: $fileName")
            println("【下载调试】MIME类型: $mimeType")
            
            // 检查下载目录是否可写
            val downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
            val canWrite = downloadDir.canWrite()
            println("【下载调试】下载目录: ${downloadDir.absolutePath}")
            println("【下载调试】下载目录是否可写: $canWrite")
            
            // 创建下载请求
            val request = DownloadManager.Request(Uri.parse(url))
            
            // 设置下载描述和标题
            request.setDescription(url)
            request.setTitle(fileName)
            println("【下载调试】设置下载标题和描述")
            
            // 获取Cookie
            val cookies = CookieManager.getInstance().getCookie(url)
            if (!cookies.isNullOrEmpty()) {
                request.addRequestHeader("Cookie", cookies)
                println("【下载调试】添加Cookie: ${cookies.take(50)}...")
            } else {
                println("【下载调试】没有Cookie可添加")
            }
            
            // 设置User-Agent
            request.addRequestHeader("User-Agent", userAgent)
            println("【下载调试】添加User-Agent: ${userAgent.take(50)}...")
            
            // 设置下载目录 - 根据Android版本选择合适的下载目录
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
                // Android 13+ 尝试两种方式
                try {
                    println("【下载调试】Android 13+: 尝试使用公共下载目录")
                    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
                    println("【下载调试】成功设置公共下载目录")
                } catch (e: Exception) {
                    println("【下载调试】设置公共下载目录失败: ${e.message}")
                    println("【下载调试】尝试使用应用专用下载目录")
                    request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, fileName)
                    println("【下载调试】成功设置应用专用下载目录")
                }
            } else {
                // Android 12及以下使用公共下载目录
                println("【下载调试】Android 12及以下: 使用公共下载目录")
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
            }
            
            // 添加额外的请求头，提高下载成功率
            request.addRequestHeader("Connection", "keep-alive")
            request.addRequestHeader("Accept", "*/*")
            
            // 设置网络类型（允许所有网络类型）
            request.setAllowedNetworkTypes(
                DownloadManager.Request.NETWORK_WIFI or 
                DownloadManager.Request.NETWORK_MOBILE
            )
            
            // 设置下载可见性
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
            
            // 允许漫游时下载
            request.setAllowedOverRoaming(true)
            
            // 添加额外的请求头，提高下载成功率
            request.addRequestHeader("Accept-Encoding", "identity") // 禁用压缩，避免某些服务器的问题
            println("【下载调试】添加Accept-Encoding: identity")
            
            request.addRequestHeader("Connection", "keep-alive")
            println("【下载调试】添加Connection: keep-alive")
            
            request.addRequestHeader("Accept", "*/*")
            println("【下载调试】添加Accept: */*")
            
            // 设置MIME类型（如果有）
            if (mimeType.isNotEmpty() && mimeType != "application/octet-stream") {
                request.setMimeType(mimeType)
                println("【下载调试】设置MIME类型: $mimeType")
            }
            
            // 设置网络类型（允许所有网络类型）
            request.setAllowedNetworkTypes(
                DownloadManager.Request.NETWORK_WIFI or 
                DownloadManager.Request.NETWORK_MOBILE
            )
            println("【下载调试】设置允许的网络类型: WIFI和移动网络")
            
            // 设置下载可见性
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
            println("【下载调试】设置下载通知可见性: VISIBILITY_VISIBLE_NOTIFY_COMPLETED")
            
            // 允许漫游时下载
            request.setAllowedOverRoaming(true)
            println("【下载调试】设置允许漫游时下载")
            
            // 开始下载
            try {
                println("【下载调试】准备将下载请求入队")
                val downloadId = downloadManager.enqueue(request)
                println("【下载调试】成功将下载请求入队: ID=$downloadId")
                
                // 检查下载ID是否有效
                if (downloadId > 0) {
                    println("【下载调试】下载ID有效: $downloadId")
                    
                    // 查询下载状态
                    try {
                        val query = DownloadManager.Query().setFilterById(downloadId)
                        val cursor = downloadManager.query(query)
                        if (cursor != null && cursor.moveToFirst()) {
                            val statusIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)
                            if (statusIndex != -1) {
                                val status = cursor.getInt(statusIndex)
                                println("【下载调试】下载初始状态: ${getStatusString(status)}")
                            } else {
                                println("【下载调试】无法获取状态列索引")
                            }
                            cursor.close()
                        } else {
                            println("【下载调试】查询下载状态失败或结果为空")
                        }
                    } catch (e: Exception) {
                        println("【下载调试】查询下载状态时出错: ${e.message}")
                    }
                    
                    // 显示下载开始的提示
                    try {
                        Toast.makeText(context, "开始下载: $fileName", Toast.LENGTH_SHORT).show()
                    } catch (e: Exception) {
                        println("【下载调试】显示Toast时出错: ${e.message}")
                    }
                } else {
                    println("【下载调试】下载ID无效: $downloadId")
                }
            } catch (e: Exception) {
                println("【下载调试】下载请求入队失败")
                println("【下载调试】错误类型: ${e.javaClass.name}")
                println("【下载调试】错误信息: ${e.message}")
                println("【下载调试】堆栈跟踪:")
                e.printStackTrace()
                
                try {
                    Toast.makeText(context, "下载请求失败: ${e.message}", Toast.LENGTH_SHORT).show()
                } catch (toastError: Exception) {
                    println("【下载调试】显示错误Toast时出错: ${toastError.message}")
                }
            }
        } catch (e: Exception) {
            try {
                Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show()
            } catch (toastError: Exception) {
                // 忽略Toast显示错误
            }
            e.printStackTrace()
        }
    }
    
    /**
     * 检查URL是否是百度APK下载链接
     */
    private fun isBaiduApkDownloadUrl(url: String): Boolean {
        val lowerUrl = url.lowercase()
        return lowerUrl.contains("ms-gdown.baidu.com") || 
               lowerUrl.contains("gdown.baidu.com") || 
               lowerUrl.contains("appcenter/pkg") ||
               lowerUrl.contains("packagemapid") ||
               lowerUrl.contains("md5hash") ||
               (lowerUrl.contains("baidu.com") && lowerUrl.contains("download"))
    }
    
    /**
     * 将下载状态码转换为可读的字符串
     */
    private fun getStatusString(status: Int): String {
        return when (status) {
            DownloadManager.STATUS_PENDING -> "等待中(PENDING)"
            DownloadManager.STATUS_RUNNING -> "下载中(RUNNING)"
            DownloadManager.STATUS_PAUSED -> "已暂停(PAUSED)"
            DownloadManager.STATUS_SUCCESSFUL -> "已完成(SUCCESSFUL)"
            DownloadManager.STATUS_FAILED -> "失败(FAILED)"
            else -> "未知状态($status)"
        }
    }
    
    /**
     * 从URL中提取文件扩展名
     */
    private fun extractExtensionFromUrl(url: String): String {
        println("【下载调试】从URL提取扩展名: $url")
        
        // 检查URL中是否包含查询参数
        val urlWithoutQuery = url.split("?")[0]
        println("【下载调试】去除查询参数后的URL: $urlWithoutQuery")
        
        // 检查URL路径中是否包含文件扩展名
        val lastDotIndex = urlWithoutQuery.lastIndexOf(".")
        if (lastDotIndex != -1 && lastDotIndex < urlWithoutQuery.length - 1) {
            val extension = urlWithoutQuery.substring(lastDotIndex + 1)
            println("【下载调试】找到可能的扩展名: $extension")
            
            // 只返回合法的文件扩展名（不超过10个字符且只包含字母和数字）
            if (extension.length <= 10 && extension.matches(Regex("[a-zA-Z0-9]+"))) {
                println("【下载调试】确认有效的扩展名: $extension")
                return extension
            } else {
                println("【下载调试】扩展名无效: $extension")
            }
        } else {
            println("【下载调试】URL中没有找到扩展名")
        }
        
        // 检查特定的下载URL模式
        if (url.contains("ms-gdown.baidu.com") || url.contains("gdown.baidu.com")) {
            return "apk"
        }
        
        // 检查URL中的文件类型提示
        val lowerUrl = url.lowercase()
        return when {
            lowerUrl.contains("filetype=apk") || lowerUrl.contains("type=apk") -> "apk"
            lowerUrl.contains("filetype=pdf") || lowerUrl.contains("type=pdf") -> "pdf"
            lowerUrl.contains("filetype=zip") || lowerUrl.contains("type=zip") -> "zip"
            lowerUrl.contains("filetype=doc") || lowerUrl.contains("type=doc") -> "doc"
            lowerUrl.contains("filetype=docx") || lowerUrl.contains("type=docx") -> "docx"
            lowerUrl.contains("filetype=xls") || lowerUrl.contains("type=xls") -> "xls"
            lowerUrl.contains("filetype=xlsx") || lowerUrl.contains("type=xlsx") -> "xlsx"
            lowerUrl.contains("filetype=ppt") || lowerUrl.contains("type=ppt") -> "ppt"
            lowerUrl.contains("filetype=pptx") || lowerUrl.contains("type=pptx") -> "pptx"
            else -> ""
        }
    }
}
